package operations

import (
	"encoding/json"
	"fmt"
	"github.com/sirupsen/logrus"
	"mydocker/common"
	"mydocker/container"
	"os"
	"path"
	"text/tabwriter"
)

// ListContainersInfo 遍历容器信息
func ListContainersInfo() {
	// 读取存放容器信息目录下的所有文件
	files, err := os.ReadDir(common.DefaultContainerInfoPath)
	if err != nil {
		logrus.Errorf("read info dir, err: %v", err)
	}
	// 获取 docker 中所有容器的信息
	infos := make([]*container.ContainerInfo, 0, len(files))
	for _, file := range files {
		info, err := getContainerInfo(file)
		if err != nil {
			logrus.Errorf("get container info, name: %s, err: %v", file.Name(), err)
			continue
		}
		infos = append(infos, info)
	}

	// 使用 tabwriter.NewWriter 在控制台打印出容器信息
	// tabwriter 是引用的 text/tabwriter 类库，用于在控制台打印对齐的表格

	// 将所有容器的信息格式化后写入 w 的缓冲区中
	w := tabwriter.NewWriter(os.Stdout, 12, 1, 3, ' ', 0)
	_, err = fmt.Fprint(w, "ID\tNAME\tPID\tIP\tSTATUS\tCOMMAND\tCREATED\n")
	if err != nil {
		logrus.Errorf("Fprint error %v", err)
	}
	for _, info := range infos {
		_, err = fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n", info.ID, info.Name, info.Pid, info.IP, info.Status, info.Command, info.CreateTime)
		if err != nil {
			logrus.Errorf("write info, err: %v", err)
		}
	}

	// 将缓冲区中的内容刷新到标准输出，即将缓冲区中的容器信息输出到标准输出
	if err = w.Flush(); err != nil {
		logrus.Errorf("flush info, err: %v", err)
	}
}

// 从 config 文件中读取容器的信息并转换成 ContainerInfo 结构体
func getContainerInfo(file os.DirEntry) (*container.ContainerInfo, error) {
	// 根据文件名拼接出完整路径
	configFileDir := path.Join(common.DefaultContainerInfoPath, file.Name(), common.ConfigName)
	// 读取容器配置文件
	content, err := os.ReadFile(configFileDir)
	if err != nil {
		logrus.Errorf("read file, path: %s, err: %v", configFileDir, err)
		return nil, err
	}
	info := new(container.ContainerInfo)
	if err = json.Unmarshal(content, info); err != nil {
		logrus.Errorf("unmarshal file, err: %v", err)
		return nil, err
	}
	return info, err
}
